package com.termux.tasker.slice;

import com.termux.tasker.*;
import com.termux.tasker.utils.FileUtils;
import com.termux.tasker.utils.Logger;
import com.termux.tasker.utils.PluginUtils;
import com.termux.tasker.utils.TermuxAppUtils;
import com.termux.tasker_ohos.ResourceTable;
import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;
import ohos.aafwk.content.IntentParams;
import ohos.agp.components.*;
import ohos.agp.components.webengine.WebView;
import ohos.agp.window.dialog.CommonDialog;

import ohos.agp.window.dialog.ToastDialog;
import ohos.agp.window.service.WindowManager;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;

import static com.termux.tasker.utils.Logger.setLogLevel;
import static ohos.agp.components.ComponentContainer.LayoutConfig.MATCH_CONTENT;

public class MainAbilitySlice extends AbilitySlice {
    private static final int WIDTH = 1000;
    private static int currentI = 1;
    private static final int LOG_OFF = 1;
    private static final int LOG_NORMAL = 2;
    private static final int LOG_DEBUG = 3;
    private static final int LOG_VERBOSE = 4;

    public static final int LOG_LEVEL_OFF = 0; // log nothing
    public static final int LOG_LEVEL_NORMAL = 1; // start logging error, warn and info messages and stacktraces
    public static final int LOG_LEVEL_DEBUG = 2; // start logging debug messages
    public static final int LOG_LEVEL_VERBOSE = 3; // start logging verbose messages
    private TextField mExecutablePathText;
    private Text mExecutablePathTextInfo;
    private TextField mArgumentsText;
    private TextField mWorkingDirectoryPathText;
    private Checkbox mInTerminalCheckbox;
    private Text mExecutableAbsolutePathText;
    private Text mWorkingDirectoryAbsolutePathText;
    private Text mTermuxAppFilesPathInaccessibleWarning;
    private Text mPluginPermissionUngrantedWarning;
    private Text mAllowExternalAppsUngrantedWarning;
    private Text more;
    private Text home;
    private Text twofortyfouramLocaleMenuDontsave;
    private Text twofortyfouramLocaleMenuSave;
    private Text help;

    private String[] executableFileNamesList = new String[0];
    private String[] workingDirectoriesNamesList = new String[0];
    Intent localeBundle;
    /**
     * 进入前台时触发
     **/
    @Override
    public void onActive() {

        super.onActive();
        checkIfPluginCanAccessTermuxApp();
        checkIfPluginHostHasPermissionRunCommand();
        try {
            processExecutablePath(mExecutablePathText == null ? null : mExecutablePathText.getText().toString());
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            processWorkingDirectoryPath(mWorkingDirectoryPathText == null ? null : mWorkingDirectoryPathText.getText().toString());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 可见时触发
     **/
    @Override
    public void onForeground(Intent intent) {
        super.onForeground(intent);
    }

    /**
     * 创建Ability时触发，仅触发一次
     **/
    @Override
    protected void onStart(Intent intent) {

        super.onStart(intent);
        getWindow().addFlags(WindowManager.LayoutConfig.MARK_TRANSLUCENT_STATUS);
        setUIContent(ResourceTable.Layout_ability_main);

        if(intent!=null) {
        BundleScrubber.scrub(intent);
            localeBundle = intent.getSequenceableParam("com.twofortyfouram.locale.intent.extra.BUNDLE");
            BundleScrubber.scrub(localeBundle);
        }



        mExecutablePathText = (TextField) findComponentById(ResourceTable.Id_executable_path);
        mExecutablePathTextInfo=(Text) findComponentById(ResourceTable.Id_executable_path_text);
        mArgumentsText = (TextField) findComponentById(ResourceTable.Id_arguments);
        mWorkingDirectoryPathText = (TextField) findComponentById(ResourceTable.Id_working_directory_path);
        mInTerminalCheckbox = (Checkbox) findComponentById(ResourceTable.Id_in_terminal);
        mExecutableAbsolutePathText = (Text) findComponentById(ResourceTable.Id_executable_absolute_path);
        mWorkingDirectoryAbsolutePathText = (Text) findComponentById(ResourceTable.Id_working_directory_absolute_path);
        mTermuxAppFilesPathInaccessibleWarning = (Text) findComponentById(ResourceTable.Id_termux_app_files_path_inaccessible_warning);
        mPluginPermissionUngrantedWarning = (Text) findComponentById(ResourceTable.Id_plugin_permission_ungranted_warning);
        mAllowExternalAppsUngrantedWarning = (Text) findComponentById(ResourceTable.Id_allow_external_apps_ungranted_warning);
        help=(Text)findComponentById(ResourceTable.Id_help);
        help.setClickedListener(new Component.ClickedListener() {
            @Override
            public void onClick(Component component) {
                WebView webView = (WebView) findComponentById(ResourceTable.Id_webview);
                final String url = "http://github.com/termux/termux-tasker"; // EXAMPLE_URL由开发者自定义
                webView.load(url);
            }
        });
        more = (Text) findComponentById(ResourceTable.Id_more);
        more.setClickedListener(new Component.ClickedListener() {
            @Override
            public void onClick(Component component) {
                moreOnclick();
            }
        });

                // 监听 executable_path 输入
        mExecutablePathText.addTextObserver(new Text.TextObserver() {
            @Override
            public void onTextUpdated(String edit, int i, int i1, int i2) {
                String editable = mExecutablePathText.getText();
                try {
                    processExecutablePath(editable == null ? null : editable);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });

        // 监听 mWorkingDirectoryPathText 输入
        mWorkingDirectoryPathText.addTextObserver(new Text.TextObserver() {
            @Override
            public void onTextUpdated(String edit, int i, int i1, int i2) {
                String editable = mWorkingDirectoryPathText.getText();
                try {
                    processWorkingDirectoryPath(editable == null ? null : editable);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });

        home = (Text) findComponentById(ResourceTable.Id_home);
        twofortyfouramLocaleMenuDontsave = (Text) findComponentById(ResourceTable.Id_twofortyfouram_locale_menu_dontsave);
        twofortyfouramLocaleMenuSave = (Text) findComponentById(ResourceTable.Id_twofortyfouram_locale_menu_save);
        home.setClickedListener(new Component.ClickedListener() {
            @Override
            public void onClick(Component component) {
                terminateAbility();
            }
        });
        twofortyfouramLocaleMenuDontsave.setClickedListener(new Component.ClickedListener() {
            @Override
            public void onClick(Component component) {
                terminateAbility();
            }
        });
        twofortyfouramLocaleMenuSave.setClickedListener(new Component.ClickedListener() {
            @Override
            public void onClick(Component component) {
                terminateAbility();
            }
        });

        if (intent == null) {
            if (localeBundle != null) {
                String errmsg;
                // If bundle is valid, then load values from bundle
                errmsg = PluginBundleManager.isBundleValid(this.getContext(), localeBundle);
                if (errmsg == null) {
                    final String selectedExecutable = localeBundle.getStringParam(PluginBundleManager.EXTRA_EXECUTABLE);
                    mExecutablePathText.setText(selectedExecutable);
                    final String selectedArguments = localeBundle.getStringParam(PluginBundleManager.EXTRA_ARGUMENTS);
                    mArgumentsText.setText(selectedArguments);
                    final String selectedWorkingDirectory = localeBundle.getStringParam(PluginBundleManager.EXTRA_WORKDIR);
                    mWorkingDirectoryPathText.setText(selectedWorkingDirectory);
                    final boolean inTerminal = Boolean.valueOf(localeBundle.getStringParam(PluginBundleManager.EXTRA_TERMINAL));
                    mInTerminalCheckbox.setChecked(inTerminal);
                } else {
                    Logger.logError(this, errmsg);
                }
            }
        }
    }

    /**
     * 状态栏更多按钮的点击事件
     **/
    public void moreOnclick() {
        DirectionalLayout titleLayout = (DirectionalLayout) LayoutScatter.getInstance(this)
                .parse(ResourceTable.Layout_radio, null, false);
        CommonDialog commonDialog = new CommonDialog(getContext());
        commonDialog
                .setContentCustomComponent(titleLayout)
                .setSize(WIDTH, MATCH_CONTENT)
                .show();
        RadioContainer container = (RadioContainer) titleLayout.findComponentById(ResourceTable.Id_radio_container);
        container.mark(currentI);
        container.setMarkChangedListener(new RadioContainer.CheckedStateChangedListener() {
            @Override
            public void onCheckedChanged(RadioContainer radioContainer, int index) {
                container.mark(index);
                currentI = index;
                commonDialog.destroy();
                radioToast(index);
            }
        });
    }

    /**
     * 切换Log
     **/
    public void radioToast(int index) {
        switch (index) {
            case LOG_OFF:
                setLogLevel(this,LOG_LEVEL_OFF);
//                Toast("Logcat log level set to \"Off\" for the plugin app and all plugin actions");
                break;
            case LOG_NORMAL:
                setLogLevel(this,LOG_LEVEL_NORMAL);
//                Toast("Logcat log level set to \"Normal\" for the plugin app and all plugin actions");
                break;
            case LOG_DEBUG:
                setLogLevel(this,LOG_LEVEL_DEBUG);
//                Toast("Logcat log level set to \"Debug\" for the plugin app and all plugin actions");
                break;
            case LOG_VERBOSE:
                setLogLevel(this,LOG_LEVEL_VERBOSE);
//                Toast("Logcat log level set to \"Verbose\" for the plugin app and all plugin actions");
                break;
        }
    }

    /**
     *
     **/
    public void finish() {
            final String executable = mExecutablePathText.getText() == null ? null : mExecutablePathText.getText().toString();
            final String arguments = mArgumentsText.getText() == null ? null : mArgumentsText.getText().toString();
            final String workingDirectory = mWorkingDirectoryPathText.getText() == null ? null : mWorkingDirectoryPathText.getText().toString();
            final boolean inTerminal = mInTerminalCheckbox.isChecked();

            if (executable != null && executable.length() > 0) {
                final Intent resultIntent = new Intent();

                /*
                 * This extra is the data to ourselves: either for the Activity or the BroadcastReceiver. Note
                 * that anything placed in this Bundle must be available to Locale's class loader. So storing
                 * String, int, and other standard objects will work just fine. Parcelable objects are not
                 * acceptable, unless they also implement Serializable. Serializable objects must be standard
                 * ohos platform objects (A Serializable class private to this plug-in's APK cannot be
                 * stored in the Bundle, as Locale's classloader will not recognize it).
                 */
                final IntentParams resultBundle = PluginBundleManager.generateBundle(getApplicationContext(), executable, arguments, workingDirectory, inTerminal);

                // The blurb is a concise status text to be displayed in the host's UI.
                final String blurb = generateBlurb(executable, arguments, inTerminal);

                // If host supports variable replacement when running plugin action, then
                // request it to replace variables in following fields
                if (TaskerPlugin.Setting.hostSupportsOnFireVariableReplacement(resultBundle)) {
                    TaskerPlugin.Setting.setVariableReplaceKeys(resultBundle, new String[]{
                            PluginBundleManager.EXTRA_EXECUTABLE,
                            PluginBundleManager.EXTRA_ARGUMENTS,
                            PluginBundleManager.EXTRA_WORKDIR
                    });
                }

                resultIntent.setParam("com.twofortyfouram.locale.intent.extra.BUNDLE", resultBundle);
                resultIntent.setParam("com.twofortyfouram.locale.intent.extra.BLURB", blurb);

                // Configuration information for Tasker variables returned from the executed task
                //
                // Do not run if we are opening a terminal, because the user might not care about this
                // if they are running something that will literally pop up in front of them (Plus
                // getting that information requires additional work for now)
                if (!inTerminal) {
                    if (TaskerPlugin.hostSupportsRelevantVariables(this.getAbility().getIntent().getParams())) {
                        TaskerPlugin.addRelevantVariableList(resultIntent, new String[]{
                                PluginResultsService.PLUGIN_VARIABLE_STDOUT + "\nStandard Output\nThe <B>stdout</B> of the command.",
                                PluginResultsService.PLUGIN_VARIABLE_STDERR + "\nStandard Error\nThe <B>stderr</B> of the command.",
                                PluginResultsService.PLUGIN_VARIABLE_EXIT_CODE + "\nExit Code\nThe <B>exit code</B> of the command. " +
                                        "0 often means success and anything else is usually a failure of some sort."
                        });
                    }
                }

                // To use variables, we can't have a timeout of 0, but if someone doesn't pay
                // attention to this and runs a task that never ends, 10 seconds seems like a
                // reasonable timeout. If they need more time, or want this to run entirely
                // asynchronously, that can be set

                if (TaskerPlugin.Setting.hostSupportsSynchronousExecution(this.getAbility().getIntent().getParams())) {
                    TaskerPlugin.Setting.requestTimeoutMS(resultIntent, 10000);
                }

                setResult(resultIntent);
            }
    }

    /**
     * The message that will be displayed by the plugin host app for the action configuration.
     * Blurb length can be a maximum of 60 characters as defined by locale lib.
     *
     * @param executable value set for the action.
     * @param arguments  value set for the action.
     * @param inTerminal value set for the action.
     * @return A blurb for the plug-in.
     */
    String generateBlurb(final String executable, final String arguments, boolean inTerminal) {
        final String stringResource = inTerminal ? "%1$s %2$s\\n\\n\\u2713 Terminal Session" : "%1$s %2$s";
        final String message = getString(Integer.parseInt(stringResource), executable, arguments);
        final int maxBlurbLength = 60; // R.integer.twofortyfouram_locale_maximum_blurb_length.
        return (message.length() > maxBlurbLength) ? message.substring(0, maxBlurbLength) : message;
    }
    /**
     * 检查插件是否可以访问TermuxApp
     **/
    private void checkIfPluginCanAccessTermuxApp() {
        if (mTermuxAppFilesPathInaccessibleWarning == null) { return; }

        String errmsg;

        // If Termux app is not installed or PREFIX_PATH is not accessible, then show warning
        errmsg = TermuxAppUtils.checkIfTermuxAppIsInstalledAndAccessible(this);
        if (errmsg != null) {
            mTermuxAppFilesPathInaccessibleWarning.setText(errmsg);
            mTermuxAppFilesPathInaccessibleWarning.setVisibility(Component.VISIBLE);
        } else {
            mTermuxAppFilesPathInaccessibleWarning.setVisibility(Component.INVISIBLE);
            mTermuxAppFilesPathInaccessibleWarning.setText(null);
        }
    }

    private void checkIfPluginHostHasPermissionRunCommand() {
        if (mPluginPermissionUngrantedWarning == null) { return; }
    }

    private void processExecutablePath(String executable) throws IOException {
        if (mExecutablePathText == null) { return; }

        boolean validate = true;
        boolean executableDefined = true;

        mExecutableAbsolutePathText.setVisibility(Component.VISIBLE);
        mExecutableAbsolutePathText.setText(null);

        if (executable == null || executable.isEmpty()) {
//            mExecutablePathText.setText("Executable required.");
            mExecutablePathTextInfo.setText("Executable required.");
            validate = false;
            executableDefined = false;
        }

        executable = FileUtils.getAbsolutePathForExecutable(executable);
        String PreAbsolutetext = "Executable Absolute Path:" + "\"%1$s\"";
        // If executable text contains a variable, then no need to set absolute path or validate the path
        if (PluginResultsService.isPluginHostAppVariableContainingString(executable)) {
            mExecutableAbsolutePathText.setText(String.format(PreAbsolutetext, "(variable detected)"));
            executable = null;
            validate = false;
        } else if (executableDefined) {
            mExecutableAbsolutePathText.setText(String.format(PreAbsolutetext, executable));
        }

        if (validate) {
            // File executableFile = new File(executable);

            String errmsg;

            // If executable is not a file, cannot be read or be executed, then return RESULT_CODE_FAILED to plugin host app
            // Readable and executable checks are to be ignored if path is in TASKER_PATH since FireReceiver will automatically
            // set read and execute permissions on execution
            errmsg = FileUtils.checkIfExecutableFileIsReadableAndExecutable(this, executable, false, true);
            if (errmsg != null) {
                mExecutablePathTextInfo.setText(errmsg);
//                mExecutablePathText.setText(errmsg);
            }

            // If executable is not in TASKER_PATH and allow-external-apps property to not set to "true", then show warning
            errmsg = PluginUtils.checkIfAllowExternalAppsPolicyIsViolated(this, executable);
            if (errmsg != null) {
                mAllowExternalAppsUngrantedWarning.setText(errmsg);
                mAllowExternalAppsUngrantedWarning.setVisibility(Component.VISIBLE);
            }
        }

        setExecutablePathTextDropdownList(executable);
    }

    private void setExecutablePathTextDropdownList(String executable) throws IOException {
        if (mExecutablePathText == null) { return; }

        File executableFile = new File("");
        File executableParentFile = new File("");
        File[] files;

        if (executable != null && !executable.isEmpty()) {
            executableFile = new File(executable);
            executableParentFile = executableFile.getParentFile();
        }

        String executablePathText = mExecutablePathText.getText().toString();

        // If executable is null, empty or executable parent is not a directory, then show files in TASKER_DIR
        if (executable == null || executable.isEmpty() || executableParentFile == null || !executableParentFile.isDirectory()) {
            files = Constants.TASKER_DIR.listFiles();
        }
        // If executable is a substring of FILES_PATH, then show files in FILES_PATH
        else if (Constants.FILES_PATH.contains(executable)) {
            executableParentFile = new File(Constants.FILES_PATH);
            files = executableParentFile.listFiles();
        }
        // If executable path in text field ends with "/", then show files in current directory instead of parent directory
        else if (executablePathText.endsWith("/")) {
            executableParentFile = executableFile;
            files = executableParentFile.listFiles();
        }
        // Else show files in parent directory
        else {
            files = executableParentFile.listFiles();
        }

        //Logger.logVerbose(this, "executable: " + executable);
        //Logger.logVerbose(this, "executablePathText: " + executablePathText);

        if (files != null && files.length > 0) {
            Arrays.sort(files);
            String executableFileNamesPrefix = "";
            // If executable is not null, empty or executable parent is not null
            if (executable != null && !executable.isEmpty() && executableParentFile != null) {
                String executableParentPath = executableParentFile.getCanonicalPath();
                //Logger.logVerbose(this, "executableParentPath: " + executableParentPath);

                // If executable path in text field starts with "/", then prefix file names with the parent directory in the drop down list
                if (executablePathText.startsWith("/"))
                { executableFileNamesPrefix = executableParentPath + "/"; }
                    // If executable path in text field starts with "$PREFIX/" or "~/", then prefix file names with the unexpanded path in the drop down list
                else if (executablePathText.startsWith("$PREFIX/") || executablePathText.startsWith("~/")) {
                    executableFileNamesPrefix = FileUtils.getUnExpandedTermuxPath(executableParentPath + "/");
                }
            }

            // Create a string array of filenames with the optional prefix for the drop down list
            executableFileNamesList = new String[files.length];
            for (int i = 0; i < files.length; i++) {
                executableFileNamesList[i] = executableFileNamesPrefix + files[i].getName();
            }
        } else {
            executableFileNamesList = new String[0];
        }

        //Logger.logVerbose(this, Arrays.toString(executableFileNamesList));

        // Update drop down list and show it
    }

    private void processWorkingDirectoryPath(String workingDirectory) throws IOException {
        if (mWorkingDirectoryPathText == null) { return; }

        boolean validate = true;
        boolean workingDirectoryDefined = true;

//        mWorkingDirectoryPathText.setText(null);
        mWorkingDirectoryAbsolutePathText.setVisibility(Component.INVISIBLE);
        mWorkingDirectoryAbsolutePathText.setText(null);

        if (workingDirectory == null || workingDirectory.isEmpty()) {
            validate = false;
            workingDirectoryDefined = false;
        }

        workingDirectory = FileUtils.getAbsolutePathForExecutable(workingDirectory);

        String Pretext = "Working Directory Absolute Path:" + "\"%1$s\"";
        // If workingDirectory text contains a variable, then no need to set absolute path or validate the path
        if (PluginResultsService.isPluginHostAppVariableContainingString(workingDirectory)) {
            mWorkingDirectoryAbsolutePathText.setText(String.format(Pretext, "(variable detected)"));
            mWorkingDirectoryAbsolutePathText.setVisibility(Component.VISIBLE);
            workingDirectory = null;
            validate = false;
        } else if (workingDirectoryDefined) {
            mWorkingDirectoryAbsolutePathText.setText(String.format(Pretext, workingDirectory));
            mWorkingDirectoryAbsolutePathText.setVisibility(Component.VISIBLE);
        }

        if (validate) {
            // File executableFile = new File(workingDirectory);

            String errmsg;

            // If workingDirectory is not a directory or cannot be read, then return RESULT_CODE_FAILED to plugin host app
            // Existence and readable checks are to be ignored if path is in HOME_PATH since FireReceiver will automatically
            // create and set read permissions on execution
            errmsg = FileUtils.checkIfDirectoryIsReadable(this, workingDirectory, false, false, true);
            if (errmsg != null) {
                mWorkingDirectoryPathText.setText(errmsg);
            }
        }

        setWorkingDirectoryPathTextDropdownList(workingDirectory);
    }

    private void setWorkingDirectoryPathTextDropdownList(String workingDirectory) throws IOException {
        if (mWorkingDirectoryPathText == null) { return; }

        File workingDirectoryFile = null;
        File workingDirectoryParentFile = null;
        File[] files;

        if (workingDirectory != null && !workingDirectory.isEmpty()) {
            workingDirectoryFile = new File(workingDirectory);
            workingDirectoryParentFile = workingDirectoryFile.getParentFile();
        }

        String workingDirectoryPathText = mWorkingDirectoryPathText.getText().toString();

        // If workingDirectory is null, empty or workingDirectory parent is not a directory, then show nothing
        if (workingDirectory == null || workingDirectory.isEmpty() || workingDirectoryParentFile == null || !workingDirectoryParentFile.isDirectory()) {
            files = new File[0];
        }
        // If workingDirectory is a substring of FILES_PATH, then show files in FILES_PATH
        else if (Constants.FILES_PATH.contains(workingDirectory)) {
            workingDirectoryParentFile = new File(Constants.FILES_PATH);
            files = workingDirectoryParentFile.listFiles();
        }
        // If workingDirectory path in text field ends with "/", then show files in current directory instead of parent directory
        else if (workingDirectoryPathText.endsWith("/")) {
            workingDirectoryParentFile = workingDirectoryFile;
            files = workingDirectoryParentFile.listFiles();
        }
        // Else show files in parent directory
        else {
            files = workingDirectoryParentFile.listFiles();
        }

        //Logger.logVerbose(this, "workingDirectory: " + workingDirectory);
        //Logger.logVerbose(this, "workingDirectoryPathText: " + workingDirectoryPathText);

        if (files != null && files.length > 0) {
            Arrays.sort(files);
            String workingDirectoryFileNamesPrefix = "";

            // If workingDirectory is not null, empty or workingDirectory parent is not null
            String workingDirectoryParentPath = workingDirectoryParentFile.getCanonicalPath();
            //Logger.logVerbose(this, "workingDirectoryParentPath: " + workingDirectoryParentPath);

            // If workingDirectory path in text field starts with "/", then prefix file names with the parent directory in the drop down list
            if (workingDirectoryPathText.startsWith("/"))
            { workingDirectoryFileNamesPrefix = workingDirectoryParentPath + "/"; }
                // If workingDirectory path in text field starts with "$PREFIX/" or "~/", then prefix file names with the unexpanded path in the drop down list
            else if (workingDirectoryPathText.startsWith("$PREFIX/") || workingDirectoryPathText.startsWith("~/")) {
                workingDirectoryFileNamesPrefix = FileUtils.getUnExpandedTermuxPath(workingDirectoryParentPath + "/");
            }

            // Create a string array of filenames with the optional prefix for the drop down list
            workingDirectoriesNamesList = new String[files.length];
            for (int i = 0; i < files.length; i++) {
                workingDirectoriesNamesList[i] = workingDirectoryFileNamesPrefix + files[i].getName();
            }
        } else {
            workingDirectoriesNamesList = new String[0];
        }

        //Logger.logVerbose(this, Arrays.toString(workingDirectoriesNamesList));
    }

    /**
     * 自定义toast
     *
     * @param string 弹出内容
     */
    public void Toast(String string) {
        // 自定义弹框标题-因为原来的titleText文字过多不换行
        DirectionalLayout toastLayout = (DirectionalLayout) LayoutScatter.getInstance(this)
                .parse(ResourceTable.Layout_layout_toast, null, false);
        // 获取text 标签
        Text title = (Text) toastLayout.findComponentById(ResourceTable.Id_toast_content);
        // 赋值
        title.setText(string);
        new ToastDialog(getContext())
                .setComponent(toastLayout)
                .setSize(MATCH_CONTENT, MATCH_CONTENT)
                .show();
    }
}
